package cn.com.generaldata.os.service.indicator_evaluation.area_marine_economic_analysis;

import org.apache.commons.lang3.Validate;
import org.nutz.dao.sql.Criteria;

import cn.com.generaldata.jsme_indicator_system.entity.IndicatorEvaluation;
import cn.com.generaldata.jsme_indicator_system.util.Constants;
import cn.com.generaldata.os.service.indicator_constant.ProvinceIndicatorConstant;
import cn.com.generaldata.os.service.indicator_evaluation.IndicatorEvaluationCalculateService;
import cn.com.generaldata.os.util.BeanMapper;
import cn.com.generaldata.os.vo.IndicatorAccountVO;

/**
 * 十个主要海洋产业增加值结构偏离指标计算类.
 */
public class MajorMarineIndustryAddValueStructOffsetCalculateService extends IndicatorEvaluationCalculateService {

	private String addValueOfMajorMarineIndustryName = ProvinceIndicatorConstant.MAJOR_MARINE_ADDVALUE_NAME;

	@Override
	protected Double calculate(IndicatorEvaluation indicator, IndicatorAccountVO indicatorAccountVO) {
		Double result = null;
		if (indicator.getSection() == Constants.INDICATOR_LEVEL_PROVINCE) {
			result = calculateProvinceResult(indicator, indicatorAccountVO);
		} else if (indicator.getSection() == Constants.INDICATOR_LEVEL_CITY) {
			// 市指标没确定先保留
		}
		return result;

	}

	/**
	 * 计算省级数据
	 * 
	 * @param indicatorAccountVO
	 * @return
	 */
	private Double calculateProvinceResult(IndicatorEvaluation indicator, IndicatorAccountVO indicatorAccountVO) {

		Double currentNationAddValueOfIndustry = getNationAddValueOfIndustry(indicatorAccountVO, indicator);

		IndicatorAccountVO lastVO = BeanMapper.map(indicatorAccountVO, IndicatorAccountVO.class);
		lastVO.setYear(indicatorAccountVO.getYear() - 1);
		Double lastNationAddValueOfIndustry = getNationAddValueOfIndustry(lastVO, indicator);

		Double R = (currentNationAddValueOfIndustry - lastNationAddValueOfIndustry) / lastNationAddValueOfIndustry;

		Double b = getProvinceB(indicator, indicatorAccountVO);

		lastVO = BeanMapper.map(indicatorAccountVO, IndicatorAccountVO.class);
		lastVO.setYear(indicatorAccountVO.getYear() - 1);
		Double b0 = getProvinceB(indicator, lastVO);

		return (b0 - b) * R;
	}

	/**
	 * 计算省级的B
	 * 
	 * @param indicator
	 * @param indicatorAccountVO
	 * @return
	 */
	private Double getProvinceB(IndicatorEvaluation indicator, IndicatorAccountVO indicatorAccountVO) {
		Double currentNationAddValueOfIndustry = getNationAddValueOfIndustry(indicatorAccountVO, indicator);
		Double nationAddValueOfMajorMarineIndustry = getNationAddValueOfMajorMarineIndustry(indicatorAccountVO,
				indicator);

		Double currentProvinceAddValueOfIndustry = getProvinceAddValueOfIndustry(indicatorAccountVO, indicator);

		Double b = (currentProvinceAddValueOfIndustry * currentNationAddValueOfIndustry)
				/ nationAddValueOfMajorMarineIndustry;

		return b;
	}

	/**
	 * 获得省级十个主要海洋产业的增加值
	 * 
	 * @param indicatorAccountVO
	 * @param indicator
	 * @return
	 */
	private Double getProvinceAddValueOfIndustry(IndicatorAccountVO indicatorAccountVO, IndicatorEvaluation indicator) {
		String indicatorName = ProvinceIndicatorConstant.MAJOR_MARINE_INDUSTRY_ADD_VALUE_MAP.get(indicator
				.getIndustryCode());
		Double result = getInputOrAccountingIndicatorValue(indicatorAccountVO, indicatorAccountVO.getYear(),
				indicatorName);
		Validate.isTrue(result != null);
		return result;
	}

	/**
	 * 获得国家十个主要海洋产业的增加值
	 * 
	 * @param indicatorAccountVO
	 * @param indicator
	 * @return
	 */
	private Double getNationAddValueOfIndustry(IndicatorAccountVO indicatorAccountVO, IndicatorEvaluation indicator) {
		IndicatorAccountVO vo = BeanMapper.map(indicatorAccountVO, IndicatorAccountVO.class);
		vo.setAreaId(ProvinceIndicatorConstant.NATION_AREA_ID);
		String industryName = ProvinceIndicatorConstant.MAJOR_MARINE_INDUSTRY_ADD_VALUE_MAP.get(indicator
				.getIndustryCode());
		Integer indicatorId = getIndicatorInputId(industryName, 7);

		Criteria cri = getIndicatorDataCri(vo, vo.getYear(), indicatorId);
		Double result = getInputIndicatorValue(cri);
		Validate.isTrue(result != null);
		return result;
	}

	/**
	 * 获得国家主要海洋产业的增加值
	 * 
	 * @param indicatorAccountVO
	 * @param indicator
	 * @return
	 */
	private Double getNationAddValueOfMajorMarineIndustry(IndicatorAccountVO indicatorAccountVO,
			IndicatorEvaluation indicator) {
		IndicatorAccountVO vo = BeanMapper.map(indicatorAccountVO, IndicatorAccountVO.class);
		vo.setAreaId(ProvinceIndicatorConstant.NATION_AREA_ID);
		Integer indicatorId = getIndicatorInputId(addValueOfMajorMarineIndustryName, null);

		Criteria cri = getIndicatorDataCri(vo, vo.getYear(), indicatorId);
		Double result = getInputIndicatorValue(cri);
		Validate.isTrue(result != null);
		return result;
	}

}
